// -*- mode: c++; coding: utf-8 -*-

/**
 *
 * ICE implementation of the FIPA Agent Management Specification.
 * See http://fipa.org/specs/fipa00023/SC00023K.html for a detailed description.
 **/

#include <ASDF.ice>
#include <PropertyService.ice>
#include <FIPATypes.ice>

module FIPA {

  interface Agent;

  exception AgentExists {};
  exception AlreadySubscribed {};

  interface AgentFactory {
    /**
     * Create an agent.
     *
     * @param name The agent's name.
     *
     * @return The agent's proxy.
     **/
    Agent* create (string name) throws AgentExists;

    /**
     * Create an agent.
     *
     * @param names The names of the agents.
     *
     * @return The sequence of created agents proxies.
     *
     * @return The names of the agents already registered.
     **/
    AgentSeq createSeq (Ice::StringSeq names, out Ice::StringSeq namesAlreadyRegistered);
  };

  interface AMS {
    /**
     * Register an agent with the agent platform.
     *
     * @param aid The proxy to the agent.
     **/
    void register (Agent* aid) throws AgentExists;

    /**
     * Deregister an agent with the agent platform.
     *
     * @param id The agent's identity.
     **/
    idempotent void deregister (Ice::Identity id);

    /**
     * Search for an agent in the agent platform.
     *
     * @param id The agent's identity.
     *
     * @return The proxy to the agent.
     **/
    idempotent Agent* search (Ice::Identity id);

    /**
     * Get the description of the agent platform.
     *
     * @return The description of the agent platform.
     **/
    idempotent ApDescription getDescription ();
  };

  // TODO: DF federation.
  interface DF extends ASD::Listener, ASD::Search {
    /**
     * Register an agent's description with the DF.
     *
     * @param desc The agent's DF description.
     **/
    void register (DfAgentDescription desc) throws AgentExists;

    /**
     * Deregister an agent with the DF.
     *
     * @param id The agent's identity.
     **/
    idempotent void deregister (Ice::Identity id);

    /**
     * Modify an agent's description with the DF.
     *
     * @param desc The agent's DF description.
     **/
    void modify (DfAgentDescription desc);

    /**
     * Search for an agent description in the DF.
     *
     * @param desc The agent's DF description.
     *
     * @return The proxies to the agents that match the description.
     **/
    idempotent AgentSeq search (DfAgentDescription desc);

    /**
     * Subscribe an agent with the DF.
     *
     * @param aid The proxy to the agent.
     **/
    void subscribe (Agent* aid) throws AlreadySubscribed;

    /**
     * Unsubscribe an agent with the DF.
     *
     * @param aid The Proxy to the agent.
     **/
    idempotent void unsubscribe (Agent* aid);
  };

  interface MTS {
    /**
     * Receive an ACL message.
     *
     * @param aclMessage The ACL message.
     **/
    ["ami"] void receiveMessage (Message m);
  };

  interface Agent {
    /**
     * Set the agent's state.
     *
     * @param st The new agent's state.
     **/
    void setState (AgentState st);

    /**
     * Get the agent's state.
     *
     * @return The new agent's state.
     **/
    idempotent AgentState getState ();

    /**
     * Receive an ACL message.
     *
     * @param aclMessage The ACL message.
     **/
    ["ami"] void receiveMessage (Message m);
    
    /**
     * Notification about a registration, deregistration or modification of an agent with the DF.
     *
     * @ param act The act of the notification.
     *
     * @param desc The agent's description.
     **/
    void dfAdv (DFAction act, DfAgentDescription desc); 

    /**
     * Terminate the agent execution.
     **/
    void destroy ();
  };

};
